/* MusicNet Alignment Tool
 *
 * Copyright (c) 2010 Joe Lambert
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */

/** section: alignment 
 * class ListViewGrouped < ListView
 * 
 * Specialised ListView for rendering Grouped items
 **/

var ListViewGrouped = Class.create(ListView, {	
	initialize: function($super, delegate)
	{
		$super(delegate);
		
		document.observe('group:add', this.dragMerge.bindAsEventListener(this));
						
		this.surface.observe('mouseout', function(event) {
			var target = event.target;
			
			// Find the currently hovered over <li>
			if(target.localName != 'li')
				return;	
				
			$$('.drag_hover').each(function(elem){
				elem.removeClassName('drag_hover');
			});
			this.drop_zone = null;
		}.bindAsEventListener(this));
		
		this.surface.observe('mouseover', function(event){
			if(!window.list_dragging)
				return;
				
			var target = event.target;
			
			// Find the currently hovered over <li>
			if(target.localName != 'li')
				target = target.up('li');
				
			// Have we found an <li>	
			if(target && target.localName == 'li')
			{
				if(!target.hasClassName('drag_hover'))
				{
					$$('.drag_hover').each(function(elem){
						elem.removeClassName('drag_hover');
					})
					target.addClassName('drag_hover');
					this.drop_zone = target;
				}
			}
			else
			{
				$$('.drag_hover').each(function(elem){
					elem.removeClassName('drag_hover');
				})
				this.drop_zone = null;
			}
		}.bindAsEventListener(this));
	},

/**
 * ListViewGrouped#dragMerge(event) -> null
 * - event (Event): Drag Event
 *  
 * Merge the dragged item with the group it was dropped on
 **/
	
	dragMerge: function(event)	
	{
		if(event && event.memo && this.drop_zone)
		{
			
			var params = "";
			
			event.memo.each(function(item){
				params += "&id[]="+item.getID();
				item.setLoading();
			});

			this.drop_zone.setLoading();
			
			params += "&gid=" + this.drop_zone.getID();
			
			new Ajax.Request(window.location.pathname+"ajax/group_add", {
				method: 'get',
				parameters: params,
				onSuccess: function(transport){
					// Update the items
					transport.responseJSON.data.items.each(function(item){
						$$("."+item.id).invoke("setDisabled");
					});
					// Update the group
					$$("."+transport.responseJSON.data.match_id).each(function(elem){
						elem.setLoading(false);
						
						transport.responseJSON.data.items.each(function(sub_item){
							var div = this.buildSubListItem(sub_item.id, sub_item.label);
							elem.insert(div);
						}.bind(this));
					}.bind(this));
				}.bind(this)
			});
		}
		
		this.drop_zone = null;
	},

/**
 * ListViewGrouped#buildSubListItem(id, label, verified) -> HTMLDom
 * - it (String): The ID of the item
 * - label (String): The string representation of the item
 * - verifed (Boolean): Is this item verified or not
 *  
 * Helper function to render each item belonging to a group
 **/
	
	buildSubListItem: function(id, label, verified)
	{
		// if(!verified)
		// 	label = "* "+label;
			
		var div = Builder.node('div', {id: 'grouped-'+id, className: 'grouped_item'}, [
			label,
			Builder.node('div', {className: 'delete'}, 'x')
		]);
		
		div.getID = function() {
			return this.id.split('-').last(); 
		};
		
		return div;
	},
	
	buildListItem: function($super, item, index)
	{
		li = $super(item, index);
		
		if(!li)
			return false;
		
		li.update();
		
		// Insert children of the group
		item.items.each(function(sub_item){
			var div = this.buildSubListItem(sub_item.id, sub_item.label, sub_item.verified);
			li.insert(div);
		}.bind(this));
		
		// Add some custom helper function
		li.setVerified = function(){
			this.setLoading(false);
			this.addClassName('verified');
			
			if(this.down('.verified'))
			{
				var elem = this.down('.verified');
				
				if(elem)
					elem.remove();
			}
			
			if(this.down('.removed'))
			{
				var elem = this.down('.removed');
				
				if(elem)
					elem.remove();
			}
			
			this.insert(Builder.node('div', {className: "verified"}));
			
			new Effect.Fade(this, {
				to: 0.2
			})
		};
		
		li.setUnVerified = function(){
			this.setLoading(false);
			this.addClassName('removed');
			
			if(this.down('.verified'))
			{
				var elem = this.down('.verified');
				
				if(elem)
					elem.remove();
			}
			
			if(this.down('.removed'))
			{
				var elem = this.down('.removed');
				
				if(elem)
					elem.remove();
			}
			
			this.insert(Builder.node('div', {className: "removed"}));
			new Effect.Fade(this, {
				to: 0.2
			})
		};
		
		return li;
	},
	
	// addGroup: function(match_id, items)
	// {
	// 	var index = this.delegate.data.length;
	// 	
	// 	var li = this.buildListItem({id: match_id, items: items, label: items.length?items[0].label:null}, index);
	// 	
	// 	// Do we have a previous instance of this group?
	// 	var old_li = $$("#groupedlist ."+match_id);
	// 	if(old_li.length)
	// 	{
	// 		var old_li = old_li[0];
	// 		
	// 		li.removeClassName('odd');
	// 		li.removeClassName('even');
	// 		
	// 		if(old_li.hasClassName('odd'))
	// 			li.addClassName('odd');
	// 		else
	// 			li.addClassName('even');
	// 			
	// 		old_li.replace(li);
	// 	}
	// 	else
	// 	{
	// 		this.list.insert(li);
	// 		
	// 		// Scroll to last element in the list
	// 		var delta = this.surface.getHeight() - this.list.getHeight();
	// 
	// 		if(delta < 0)
	// 			this.surface.scrollTop = 0-delta;	
	// 	}
	// },
	
	singleClick: function($super, event)
	{
		if(event.target.hasClassName('delete'))
		{
			var elem = event.target.up('.grouped_item');
			var group_elem = event.target.up('li');
			
			if(!group_elem.hasClassName('removed'))
			{
				event.stop();
				
				if(elem && group_elem)
					this.delegate.removeItemFromGroup(elem.getID(), group_elem.getID());
			}
		}
		else
			$super(event);
	}
});